package io.renren.system.job.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.renren.common.constant.Constant;
import io.renren.common.page.PageData;
import io.renren.common.service.impl.BaseServiceImpl;
import io.renren.common.utils.ConvertUtils;
import io.renren.system.job.dao.ScheduleJobDao;
import io.renren.system.job.dto.ScheduleJobDTO;
import io.renren.system.job.entity.ScheduleJobEntity;
import io.renren.system.job.service.ScheduleJobService;
import io.renren.system.job.utils.ScheduleUtils;
import io.renren.common.utils.StringUtils;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 【系统设置-定时任务】
 */
@Service
public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJobDao, ScheduleJobEntity> implements ScheduleJobService {
    @Autowired
    private Scheduler scheduler;

    private QueryWrapper<ScheduleJobEntity> getWrapper(Map<String, Object> params) {
        String beanName = StringUtils.checkObj2Str(params.get("beanName"));
        String cronExpression = StringUtils.checkObj2Str(params.get("cronExpression"));
        QueryWrapper<ScheduleJobEntity> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(beanName), "bean_name", beanName);
        wrapper.eq(StringUtils.isNotEmpty(cronExpression), "cron_expression", cronExpression);
        return wrapper;
    }

    /**
     * 根据查询条件分页获取定时任务配置列表
     *
     * @param params
     * @return
     */
    @Override
    public PageData<ScheduleJobDTO> page(Map<String, Object> params) {
        IPage<ScheduleJobEntity> page = baseDao.selectPage(
                getPage(params, Constant.CREATE_DATE, false), getWrapper(params)
        );
        return getPageData(page, ScheduleJobDTO.class);
    }

    /**
     * 根据主键获取定时任务配置详细信息
     *
     * @param id
     * @return
     */
    @Override
    public ScheduleJobDTO get(Long id) {
        ScheduleJobEntity entity = baseDao.selectById(id);
        return ConvertUtils.sourceToTarget(entity, ScheduleJobDTO.class);
    }

    /**
     * 新增保存定时任务配置信息
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(ScheduleJobDTO dto) {
        ScheduleJobEntity entity = ConvertUtils.sourceToTarget(dto, ScheduleJobEntity.class);
        entity.setStatus(Constant.ScheduleStatus.NORMAL.getValue());
        this.insert(entity);
        ScheduleUtils.createScheduleJob(scheduler, entity);
    }

    /**
     * 修改保存定时任务配置信息
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ScheduleJobDTO dto) {
        ScheduleJobEntity entity = ConvertUtils.sourceToTarget(dto, ScheduleJobEntity.class);
        ScheduleUtils.updateScheduleJob(scheduler, entity);
        this.updateById(entity);
    }

    /**
     * 根据主键删除定时任务配置信息
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] ids) {
        for (Long id : ids) {
            ScheduleUtils.deleteScheduleJob(scheduler, id);
        }
        //删除数据
        this.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 批量更新定时任务状态
     *
     * @param ids
     * @param status
     * @return
     */
    @Override
    public int updateBatch(Long[] ids, int status) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("ids", ids);
        map.put("status", status);
        return baseDao.updateBatch(map);
    }

    /**
     * 立即执行定时任务
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void run(Long[] ids) {
        for (Long id : ids) {
            ScheduleUtils.run(scheduler, this.selectById(id));
        }
    }

    /**
     * 暂停运行定时任务
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pause(Long[] ids) {
        for (Long id : ids) {
            ScheduleUtils.pauseJob(scheduler, id);
        }
        this.updateBatch(ids, Constant.ScheduleStatus.PAUSE.getValue());
    }

    /**
     * 恢复运行定时任务
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resume(Long[] ids) {
        for (Long id : ids) {
            ScheduleUtils.resumeJob(scheduler, id);
        }
        this.updateBatch(ids, Constant.ScheduleStatus.NORMAL.getValue());
    }
}